package test.t1;

import io.ktor.server.routing.Routing;
import io.micrometer.core.instrument.*;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.exporter.common.TextFormat;

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.noear.solon.Solon;
import org.noear.solon.core.route.Router;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

/**
 # HELP myapp_online_users 当前在线用户数
 # TYPE myapp_online_users gauge
 myapp_online_users{path="api/hello",} 100.0
 # HELP myapp_http_requests_total
 # TYPE myapp_http_requests_total counter
 myapp_http_requests_total{status="success",} 7.0
 # HELP myapp_request_size_bytes_max
 # TYPE myapp_request_size_bytes_max gauge
 myapp_request_size_bytes_max 128.0
 # HELP myapp_request_size_bytes
 # TYPE myapp_request_size_bytes summary
 myapp_request_size_bytes_count 7.0
 myapp_request_size_bytes_sum 896.0
 # HELP myapp_http_request_duration_seconds
 # TYPE myapp_http_request_duration_seconds summary
 myapp_http_request_duration_seconds_count 7.0
 myapp_http_request_duration_seconds_sum 0.400925398
 # HELP myapp_http_request_duration_seconds_max
 # TYPE myapp_http_request_duration_seconds_max gauge
 myapp_http_request_duration_seconds_max 0.090424699
 */
public class MicrometerStandalone {

    // 1. 创建 Prometheus MeterRegistry
    public static final PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);

    // 2. 定义指标
    static final Counter requestCounter = registry.counter(
        "myapp_http_requests_total", "status", "success"
    );

    static final Timer requestTimer = registry.timer("myapp_http_request_duration_seconds");

    static final DistributionSummary payloadSize = registry.summary("myapp_request_size_bytes");

    private static final AtomicLong onlineUsers = new AtomicLong(0);
    static Gauge onlineUsersGauge = Gauge.builder("myapp_online_users", onlineUsers, AtomicLong::get)
            .tag("path", "api/hello")
            .description("当前在线用户数").register(registry);

    public static void main(String[] args) throws IOException {
        // 3. 启动 Prometheus 暴露服务（/metrics）
        HttpServer server = HttpServer.create(new InetSocketAddress(9390), 0);
        server.createContext("/metrics", new MetricsHandler());
        server.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        server.start();

        // 4. 启动一个简单的 HTTP 服务，模拟业务接口
        HttpServer httpServer = HttpServer.create(new InetSocketAddress(9391), 0);
        httpServer.createContext("/api/hello", exchange -> {
            long start = System.nanoTime();

            // 模拟业务逻辑
            try { Thread.sleep((long) (Math.random() * 100)); } catch (InterruptedException ignored) {}

            // 记录指标
            requestCounter.increment();
            requestTimer.record(Duration.ofNanos(System.nanoTime() - start));
            payloadSize.record(128); // 模拟请求大小
            onlineUsers.set(100L);


            // 返回响应
            String response = "Hello from standalone Micrometer!";
            exchange.sendResponseHeaders(200, response.getBytes().length);
            try (OutputStream os = exchange.getResponseBody()) {
                os.write(response.getBytes());
            }
        });

        httpServer.setExecutor(Executors.newFixedThreadPool(1));
        httpServer.start();

        System.out.println("🚀 Test API: http://localhost:9391/api/hello");
        System.out.println("📊 Metrics: http://localhost:9390/metrics");
    }

    // 5. Metrics 处理器
    static class MetricsHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            // 设置响应头
            exchange.getResponseHeaders().set("Content-Type", TextFormat.CONTENT_TYPE_004);
            exchange.sendResponseHeaders(200, 0);
            // 输出指标
            try (OutputStream os = exchange.getResponseBody();
                 PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, java.nio.charset.StandardCharsets.UTF_8))
            ) {
                TextFormat.write004(writer, registry.getPrometheusRegistry().metricFamilySamples());
            }
        }
    }

}